﻿#include "CenterSceneMrg.h"
#include "AccountMgr/CenterAccountMgr.h"
#include "CenterService.h"
#include "ProtoBuffer/AllProtocol.h"
#include "Common/TableData/MapMapCfg.h"
#include "Common/Utility/ServerTime.h"
#include "Common/AccountDefine.h"
#include "Duplicate/CenterDuplicateMgr.h"
#include "Common/Event/Event.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "EscortMgr/EscortMgr.h"
#include "Common/TableDataEx/MapCfg.h"

CenterSceneMgr::CenterSceneMgr():
	m_sceneIdCount(1),
	m_updateTimeStamp(g_GetGlobalServerTime()->Tick())
{
	m_mapLogicCount.clear();
	m_mapLogicIds.clear();
	m_logicRegisterMaps.clear();
}

CenterSceneMgr::~CenterSceneMgr()
{
}

bool CenterSceneMgr::Init()
{
	IMessageDispatch *pMessageDispatch = g_GetCenterService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}
	pMessageDispatch->registerServerHandler(EMODULE_ID_SCENE, this);

	return true;
}

bool CenterSceneMgr::UnInit()
{
	IMessageDispatch *pMessageDispatch = g_GetCenterService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}
	pMessageDispatch->unregisterServerHandler(EMODULE_ID_SCENE);
	m_mapLogicCount.clear();
	return true;
}

void CenterSceneMgr::Update(uint64_t tick)
{
	/*int32_t diffSec = (int32_t)(tick - m_updateTimeStamp);
	if (diffSec > UPDATE_SECENE_TIME)
	{
		MAPALLSCENES::iterator miter = m_logicScenes.begin();
		MAPALLSCENES::iterator miterEnd = m_logicScenes.end();
		for (; miter != miterEnd; miter++)
		{
			CurCenterSceneInfo& cur = miter->second;
			diffSec = (int32_t)(tick - cur.startTimestrap);
			if (diffSec > SECENE_EXIST_TIME && cur.startTimestrap > 0 && cur.OnlineCount == 0)
			{
				LogErrFmtPrint("CenterSceneMgr::Update, check scene exist timeout, mapId:%d, sceneId:%d, timeout:%d, zid:%d",
					cur.mapId, cur.sceneId, diffSec, g_GetCenterService()->GetID());
			}
		}
		m_updateTimeStamp = g_GetGlobalServerTime()->Tick();
	}*/
}

void CenterSceneMgr::onServerMessage(uint32_t actionId, RECV_PACKAGE &package)
{
	switch (actionId)
	{
	case LOGIC_NOTIFY_DESTORY_SCENE_CENTER:
		LogicDestroySceneReq(package);
		break;
	case CENTER_CREATE_SCENE_RSP_LOGIC:
		LogicCreateSceneRsp(package);
		break;
	case LOGIC_CREATURE_TRANS_SCENE_REQ_CENTER:
		CreatureTransSceneReq(package);
		break;
	default:
		break;
	}
}

CurCenterSceneInfo* CenterSceneMgr::GetCurSceneInfoBySceneId(uint32_t sceneId)
{
	MAPALLSCENES::iterator iter = m_logicScenes.find(sceneId);
	if (iter == m_logicScenes.end())
		return nullptr;

	return &iter->second;
}

uint32_t CenterSceneMgr::GetLogicIdByMapId(uint32_t mapId)
{
	MAPCOFNIG::iterator iter = m_mapLogicIds.find(mapId);
	if (iter == m_mapLogicIds.end())
		return 0;
	return iter->second;
}

bool CenterSceneMgr::LogicMapRegister(LogicCenterRegister &sceneRegister)
{
	uint32_t logicId = sceneRegister.logicid();

	//初始化逻辑节点人数
	InitLogicCount(logicId);

	char logInfo[LOGBUFF_SIZE];
	memset(logInfo, LOGBUFF_SIZE, 0);
	uint32_t mapId = 0;
	const MapMapCfgInfo*  pMapCfg = nullptr;

	for (int i = 0; i < sceneRegister.mapids_size(); i++)
	{
		mapId = sceneRegister.mapids(i);

		if (mapId <= 0)
			continue;

		m_mapLogicIds[mapId] = logicId;
		m_logicRegisterMaps[logicId].push_back(mapId);

		pMapCfg = g_GetMapMapCfgTable()->GetMapMapCfgInfo(mapId);
		if (pMapCfg && pMapCfg->mapType != DYNAMIC_MAP)
		{
			if (GetCurSceneInfoBySceneId(mapId))
			{
				LogErrFmtPrint("register static scene error, have repeat static mapId in this group, id:%d, logicId:%d", mapId, logicId);
				m_logicScenes[mapId].OnlineCount = 0;
			}
			else
			{
				CurCenterSceneInfo scence;
				scence.logicId = logicId;
				scence.mapId = mapId;
				scence.sceneId = mapId;
				scence.OnlineCount = 0;
				scence.startTimestrap = 0;
				m_logicScenes[mapId] = scence;
			}
		}
	}

	return true;
}

bool CenterSceneMgr::LogicCrash(uint32_t logicId)
{
	//逻辑服断开连接,直接删除该逻辑节点的场景
	MAPALLSCENES::iterator iterScene = m_logicScenes.begin();
	while (iterScene != m_logicScenes.end())
	{
		CurCenterSceneInfo &curInfo = iterScene->second;
		if (logicId != curInfo.logicId)
		{
			++iterScene;
			continue;
		}
		LogInfoFmtPrint("CenterSceneMgr::LogicCrash...logicid:%u, sceneid:%u, mapid:%u ",logicId,curInfo.sceneId,curInfo.mapId);
		iterScene = m_logicScenes.erase(iterScene);
	}

	//删除改逻辑节点人数
	RemoveLogicCount(logicId);

	return true;
}

//分配一个新的场景ID
uint32_t CenterSceneMgr::AllocNewScene()
{
	uint32_t sceneId = 0;
	const MapMapCfgInfo*  pMapCfg = nullptr;
	do
	{
		sceneId = m_sceneIdCount++;
		pMapCfg = g_GetMapMapCfgTable()->GetMapMapCfgInfo(sceneId);
	} while (pMapCfg);

	return sceneId;
}

bool CenterSceneMgr::CenterCreateScene(uint32_t mapId, uint32_t &sceneIdOut, uint32_t &logicSerId, CreateSceneParamProto &paramProto, bool notifyLogic)
{
	uint32_t logicId = GetLogicIdByMapId(mapId);
	if (logicId <= 0)
	{
		return false;
	}
	//分配场景
	uint32_t sceneId = AllocNewScene();
	if (sceneId <= 0)
	{
		return false;
	}
	sceneIdOut = sceneId;
	logicSerId = logicId;
	//

	if (notifyLogic)
	{
		CenterCreateSceneReq gateCreate;
		gateCreate.set_mapid(mapId);
		gateCreate.set_sceneid(sceneId);
		CreateSceneParamProto *pParam = gateCreate.mutable_param();
		if (nullptr != pParam)
		{
			pParam->CopyFrom(paramProto);
		}

		return g_GetCenterService()->SendDataToLogic(logicId, EMODULE_ID_SCENE, CENTER_CREATE_SCENE_REQ_LOGIC, &gateCreate);
	}
	return true;
}

bool CenterSceneMgr::LogicCreateSceneRsp(RECV_PACKAGE& package)
{
	bool result = false;
	bool retCode = false;

	CenterCreateSceneRsp logiccreateRsp;
	retCode = logiccreateRsp.ParseFromArray(package.dataAfterHead, package.sizeAfterHead);
	MMO_PROCESS_ERROR(retCode);
	{
		uint32_t sceneId = logiccreateRsp.sceneid();
		uint32_t mapId = logiccreateRsp.mapid();
		uint32_t logicId = package.session->GetUserData().v32;

		CurCenterSceneInfo newScene;
		newScene.logicId = logicId;
		newScene.mapId = mapId;
		newScene.sceneId = sceneId;
		newScene.OnlineCount = 0;
		newScene.startTimestrap = g_GetGlobalServerTime()->Tick();
		m_logicScenes[sceneId] = newScene;
	}
Exit0:
	return result;


}

//逻辑服生物切场景请求
bool CenterSceneMgr::CreatureTransSceneReq(RECV_PACKAGE& package)
{
	uint32_t zid = g_GetCenterService()->GetID();
	uint32_t srcLogicId = package.session->GetUserData().v32;
	LogicCreatureTransSceneReq trans;
	if (!trans.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		LogErrFmtPrint("[center] LogicCreatureTransSceneReq, parse failed.. zid:%u ", zid);
		return false;
	}
	uint32_t curSceneId = trans.cursceneid();
	uint32_t dstSceneId = trans.dstsceneid();
	//const CreatureTransParam &trans_param = trans.param();
	CreatureTransParam trans_param;
	trans_param.CopyFrom(trans.param());
	int32_t creature_kind = trans_param.creature_kind();
	uint64_t creature_cid = trans_param.creature_cid();
	UidGameInfo *pUid = nullptr;
	int32_t ret = RET_FAIL;
	CurCenterSceneInfo *pdstScene = nullptr;
	//
	LogDebugFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq...curscene:%u, dstsceneid:%u , kind:%d, cid:%llu ",curSceneId,dstSceneId,creature_kind,creature_cid);
	
	if (CREATURE_PLAYER == creature_kind) //玩家的判断，后面添加
	{
		if (!trans_param.has_player_param())
		{
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, trans_param.has_player_param() return false, can not trans to dest scene cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}
		
		PlayerTransParam &protoPlayerTrans = const_cast<PlayerTransParam&>(trans_param.player_param());
		CharacterDBBaseInfo &protoDBBaseInfo = const_cast<CharacterDBBaseInfo&>(protoPlayerTrans.info().basedata());
		uint32_t clientId = protoPlayerTrans.client_id();
		uint32_t sceneId = protoDBBaseInfo.enter_scene_id();
		uint32_t mapId = protoDBBaseInfo.enter_map_id();
		pUid = g_GetCenterAccountMgr()->GetUidGameInfo(clientId);
		if (nullptr == pUid)
		{
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, nullptr == pUid... cid:%llu, clientid:%u ", creature_cid, clientId);
			goto Exit1;
		}
		if (pUid->state != UID_STATE_GAMING)
		{
			//切场景的时候必须处于游戏状态
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, pUid->state != UID_STATE_GAMING ... cid:%llu, uid:%u ，state:%u ", creature_cid, pUid->uid, pUid->state);
			goto Exit1;
		}
		if (pUid->playCid != creature_cid)
		{
			//切场景的时候必须处于游戏状态
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, pUid->playCid != cid... cid:%llu, uid:%u, oldcid:%llu", creature_cid, pUid->uid, pUid->playCid);
			goto Exit1;
		}
		pdstScene = GetCurSceneInfoBySceneId(dstSceneId);
		if (g_GetMapCfgMgr()->IsUnionHomeMap(mapId)
			|| g_GetMapCfgMgr()->IsUnionDunGeonMap(mapId)
			) //是工会驻地地图,单独处理
		{
			//是否是工会场景，有可能玩家从工会场景进入副本，在打副本的过程中，被踢出工会或者工会解散
			bool bResetFlag = false;//重新设置地图标志
			if (nullptr == pdstScene) 
			{
				//目标场景不存在，可能工会解散，工会地图被回收了
				bResetFlag = true;
			}
			else if (!g_GetCenterDuplicateMgr()->transCanEnter(dstSceneId, creature_cid, creature_kind))
			{
				//不能进入工会地图，可能被踢出工会了
				bResetFlag = true;
			}
			if (bResetFlag) //需要重置，如果找不到工会场景，或者不能进入工会场景了，直接重置到 主城
			{
				uint32_t mainCityMapId = g_GetMapCfgMgr()->GetMainCityMapId();
				const Point3<float> &mainCityPos = g_GetMapCfgMgr()->GetMainCityBornPos();
				pdstScene = GetCurSceneInfoBySceneId(mainCityMapId);
				if (nullptr == pdstScene)
				{
					ret = RET_SCENE_DST_NOT_EXIST;
					LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq 00, nullptr == pdstScene, can not find main city scene... cid:%llu, sceneId:%u, dstScene:%u, oldscene:%u,oldmap:%u", creature_cid, curSceneId, mainCityMapId,sceneId,mapId);
					goto Exit1;
				}
				//重置了地图和坐标，需要修改数据
				sceneId = pdstScene->sceneId;
				mapId = pdstScene->mapId;
				protoDBBaseInfo.set_enter_map_id(mapId);
				protoDBBaseInfo.set_enter_scene_id(sceneId);
				protoDBBaseInfo.set_enterposx(mainCityPos.x);
				protoDBBaseInfo.set_enterposy(mainCityPos.y);
				protoDBBaseInfo.set_enterposz(mainCityPos.z);
			}

		}
		else if (nullptr == pdstScene) //目标场景不存在
		{
			ret = RET_SCENE_DST_NOT_EXIST;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq 11, nullptr == pdstScene, can not find scene... cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}
		else if (!g_GetCenterDuplicateMgr()->transCanEnter(dstSceneId, creature_cid, creature_kind))
		{
			//不能进入
			ret = RET_SCENE_DST_NOT_EXIST;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq 12, nullptr == pdstScene, can not trans to dest scene cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}
		

		//玩家参数携带的 目标场景和地图 需要跟传到中心服的一致
		if (pdstScene->sceneId != sceneId || pdstScene->mapId != mapId)
		{
			//参数错误
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, pdstScene->sceneId != sceneId || pdstScene->mapId != mapId... cid:%llu, uid:%u, req:[%u,%u]  param:[%u,%u]", creature_cid, pUid->uid, pdstScene->sceneId, pdstScene->mapId, sceneId, mapId);
			goto Exit1;
		}


		if (pUid->logicId == pdstScene->logicId)
		{
			//目标逻辑服和源逻辑服相同
			LogWarningFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq....pUid->logicId == pdstScene->logicId.....uid:%u ,cid:%llu, srclogicid:%u, dstlogicid:%u ", pUid->uid, creature_cid, pUid->logicId, pdstScene->logicId);
		}
		//
		CharLoginSyncCenterData *protoCenterData = protoPlayerTrans.mutable_center_data();
		if (nullptr != protoCenterData)
		{
			g_GetCenterAccountMgr()->CharLoginCenterData(creature_cid, *protoCenterData);
		}
	}
	else if (CREATURE_MONSTER == creature_kind)	//monster
	{
		pdstScene = GetCurSceneInfoBySceneId(dstSceneId);
		if (nullptr == pdstScene) //目标场景不存在
		{
			ret = RET_SCENE_DST_NOT_EXIST;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq 11, nullptr == pdstScene, can not find scene... cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}
		else if (!g_GetCenterDuplicateMgr()->transCanEnter(dstSceneId, creature_cid, creature_kind))
		{
			//不能进入
			ret = RET_SCENE_DST_NOT_EXIST;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq 12, nullptr == pdstScene, can not trans to dest scene cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}
		if (!trans_param.has_mons_param())
		{
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, trans_param.has_mons_param() return false, can not trans to dest scene cid:%llu, sceneId:%u, dstScene:%u ", creature_cid, curSceneId, dstSceneId);
			goto Exit1;
		}

		const MonsterMonsterCfgInfo *pCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(trans_param.mons_param().monster_id());
		if (nullptr == pCfg)
		{
			ret = RET_FAIL;
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, MonsterMonsterCfgInfo *pCfg = nullptr.....  monster_id=[%u]", trans_param.mons_param().monster_id());
			goto Exit1;
		}

		if (/*PARENT_MONSTER_TYPE_MOVE_BIAOCHE*/9 == pCfg->parentType || /*PARENT_MONSTER_TYPE_MOVE_TEAM_BIAOCHE*/11 == pCfg->parentType)
		{
			Escort *pEscort = g_GetEscortMgr()->FindEscortByEsctId(trans_param.mons_param().monster_cid());
			if (nullptr == pEscort || pEscort->CID() <= 0)
			{
				ret = RET_FAIL;
				LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, escort not exist....escort_cid=[%llu]", trans_param.mons_param().monster_cid());
				goto Exit1;
			}
		
			MonsterTransParam::EscortParam *escort_param = trans_param.mutable_mons_param()->mutable_escort();
			if (nullptr == escort_param)
			{
				ret = RET_FAIL;
				LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq, MonsterTransParam::EscortParam *escort_param=nullptr");
				goto Exit1;
			}
			escort_param->set_escort_id(pEscort->EscortID());
			escort_param->set_path_id(pEscort->LineID());
			escort_param->set_type(pEscort->Type());
		}
	}

	ret = RET_SUCCESS;
Exit1:
	//先通知源逻辑节点
	CenterCreatureTransSceneResultRsp rsp;
	rsp.set_result(ret);
	rsp.set_cur_sceneid(curSceneId);
	rsp.set_dst_sceneid(dstSceneId);
	rsp.set_creature_cid(creature_cid);
	rsp.set_creature_kind(creature_kind);
	if (!g_GetCenterService()->SendDataToLogic(srcLogicId, EMODULE_ID_SCENE, CENTER_CREATURE_TRANS_SCENE_RSP_LOGIC_RESULT,&rsp))
	{
		LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq..... SendDataToLogic failed...srcLogicId:%u, cid:%llu, kind:%d, sceneId:%u, dstScene:%u , ret:%d ", srcLogicId,creature_cid, creature_kind, curSceneId, dstSceneId, ret);
	}
	else if (RET_SUCCESS == ret)
	{
		CenterCreatureTransSceneSuccessRsp dstRsp;
		dstRsp.set_dst_sceneid(pdstScene->sceneId);
		dstRsp.set_dst_mapid(pdstScene->mapId);
		CreatureTransParam *protoParam = dstRsp.mutable_param();
		if (nullptr != protoParam)
		{
			protoParam->CopyFrom(trans_param);
		}
		if (!g_GetCenterService()->SendDataToLogic(pdstScene->logicId, EMODULE_ID_SCENE, CENTER_CREATURE_TRANS_SCENE_RSP_LOGIC_SUCCESS, &dstRsp))
		{
			LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq..... SendDataToLogic failed...dstLogicId:%u  cid:%llu, kind:%d, sceneId:%u, dstScene:%u , ret:%d ", pdstScene->logicId, creature_cid, creature_kind, curSceneId, dstSceneId, ret);
		}
		else
		{
			if (nullptr != pUid) //玩家才有账号信息
			{
				//账号准备切换逻辑节点处理
				if (!g_GetCenterAccountMgr()->OnPrepareChangeScene(creature_cid, pUid->clientId, pUid->uid, pdstScene->logicId))
				{
					LogErrFmtPrint("[center] CenterSceneMgr::CreatureTransSceneReq... OnPrepareChangeScene failed....uid:%u, cid:%llu,sceneid:%u, srcLogicId:%u, dstlogicid:%u, dstsceneid:%u ", pUid->uid, creature_cid, curSceneId, srcLogicId, pdstScene->logicId, dstSceneId);
				}
			}	

			//这里是全部校验完成了，发送准备传送事件
			TransPrepareEvent prepareEvent;
			prepareEvent.creature_cid = creature_cid;
			prepareEvent.creature_kind = creature_kind;
			prepareEvent.dstSceneId = dstSceneId;
			prepareEvent.dstLogicId = pdstScene->logicId;
			g_GetEvent()->FireExecute(EVENT_TRANS_PREPARE, creature_cid, creature_kind, &prepareEvent, sizeof(prepareEvent));
		}
	}
	return true;
}


void CenterSceneMgr::LeaveGame(uint32_t sceneId)
{
	CurCenterSceneInfo *pScene = GetCurSceneInfoBySceneId(sceneId);
	if (nullptr == pScene)
	{
		//LogErrFmtPrint("LeaveGame, cannt enterscene sceneId:%d, cid:%d, dstScene:%d, srcScene:%p", sceneId, pScene);
		LogErrFmtPrint("LeaveGame, cannt enterscene sceneId:%d, srcScene:%p", sceneId, pScene);
		return;
	}
	pScene->OnlineCount--;
}

void CenterSceneMgr::LoginGame(uint32_t sceneId)
{
	CurCenterSceneInfo *pScene = GetCurSceneInfoBySceneId(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("LoginGame, cannt enterscene sceneId:%d, srcScene:%p", sceneId, pScene);
		return;
	}
	pScene->OnlineCount++;
}

void CenterSceneMgr::EnterLogic(uint32_t logicId) //进入逻辑服
{
	MAP_UINT32_INT32::iterator iter = m_mapLogicCount.find(logicId);
	if (iter != m_mapLogicCount.end())
	{
		iter->second += 1;
	}
}

void CenterSceneMgr::LeaveLogic(uint32_t logicId) //离开逻辑服
{
	MAP_UINT32_INT32::iterator iter = m_mapLogicCount.find(logicId);
	if (iter != m_mapLogicCount.end())
	{
		if (iter->second > 0)
		{
			iter->second -= 1;
		}
	}
}

void CenterSceneMgr::ChangeLogic(uint32_t oldLogicId, uint32_t newLogicId) //切换逻辑服
{
	LeaveLogic(oldLogicId);
	EnterLogic(newLogicId);
}

//初始化逻辑节点人数
void CenterSceneMgr::InitLogicCount(uint32_t logicId)
{
	m_mapLogicCount[logicId] = 0;
}
//移除逻辑节点
void CenterSceneMgr::RemoveLogicCount(uint32_t logicId)
{
	m_mapLogicCount.erase(logicId);
}

bool CenterSceneMgr::LogicDestroySceneReq(RECV_PACKAGE& package)
{
	bool result = false;
	bool retCode = false;

	NotifyLogicSceneClose closeScene;
	uint32_t sceneId = 0;
	uint32_t mapId = 0;
	uint32_t logicId = package.session->GetUserData().v32;
	CurCenterSceneInfo *pDelScene = nullptr;
	retCode = closeScene.ParseFromArray(package.dataAfterHead, package.sizeAfterHead);
	MMO_PROCESS_ERROR(retCode);
	sceneId = closeScene.sceneid();
	mapId = closeScene.mapid();
	LogDebugFmtPrint("[center] LogicDestroySceneReq....close scene, logicid:%u , sceneId:%u, mapId:%u", logicId, sceneId, mapId);
	pDelScene = GetCurSceneInfoBySceneId(sceneId);
	if (nullptr != pDelScene)
	{
		if (pDelScene->logicId != logicId)
		{
			LogErrFmtPrint("[center] LogicDestroySceneReq....pDelScene->logicId != logicId...logicid:%u ,sceneLogicId:%u, sceneId:%u, mapId:%u ", logicId,pDelScene->logicId, sceneId, mapId);
		}
	}
	else
	{
		LogErrFmtPrint("[center] LogicDestroySceneReq....can not find scene...logicid:%u , sceneId:%u, mapId:%u ", logicId, sceneId, mapId);
	}
	//
	m_logicScenes.erase(sceneId);
	result = true;
Exit0:
	return result;
}

//获取人数最少的逻辑节点ID
uint32_t CenterSceneMgr::GetMinCountLogicId()
{
	uint32_t logicId = 0;
	int32_t count = -1;
	MAP_UINT32_INT32::iterator iter = m_mapLogicCount.begin();
	for (; iter != m_mapLogicCount.end(); ++iter)
	{
		if (-1 == count)
		{
			count = iter->second;
			logicId = iter->first;
		}
		else if (count > iter->second)
		{
			count = iter->second;
			logicId = iter->first;
		}
	}
	return logicId;
}